package tests

import java.math.*
import java.util.*
import kotlin.test.*
import org.testng.annotations.*

import com.chronoxor.proto.*
import com.chronoxor.test.*

@Suppress("ReplaceAssertBooleanWithAssertEquality")
class TestSerializationJson
{
    @Test
    fun serializationJsonDomain()
    {
        // Define a source JSON string
        var json = """{"id":1,"name":"Test","state":6,"wallet":{"currency":"USD","amount":1000.0},"asset":{"currency":"EUR","amount":100.0},"orders":[{"id":1,"symbol":"EURUSD","side":0,"type":0,"price":1.23456,"volume":1000.0},{"id":2,"symbol":"EURUSD","side":1,"type":1,"price":1.0,"volume":100.0},{"id":3,"symbol":"EURUSD","side":0,"type":2,"price":1.5,"volume":10.0}]}"""

        // Create a new account from the source JSON string
        val account1 = Account.fromJson(json)

        // Serialize the account to the JSON string
        json = account1.toJson()

        // Check the serialized JSON size
        assertTrue(json.isNotEmpty())

        // Deserialize the account from the JSON string
        val account2 = Account.fromJson(json)

        assertEquals(account2.id, 1)
        assertEquals(account2.name, "Test")
        assertTrue(account2.state.hasFlags(State.good))
        assertEquals(account2.wallet.currency, "USD")
        assertEquals(account2.wallet.amount, 1000.0)
        assertNotEquals(account2.asset, null)
        assertEquals(account2.asset!!.currency, "EUR")
        assertEquals(account2.asset!!.amount, 100.0)
        assertEquals(account2.orders.size, 3)
        assertEquals(account2.orders[0].id, 1)
        assertEquals(account2.orders[0].symbol, "EURUSD")
        assertEquals(account2.orders[0].side, OrderSide.buy)
        assertEquals(account2.orders[0].type, OrderType.market)
        assertEquals(account2.orders[0].price, 1.23456)
        assertEquals(account2.orders[0].volume, 1000.0)
        assertEquals(account2.orders[1].id, 2)
        assertEquals(account2.orders[1].symbol, "EURUSD")
        assertEquals(account2.orders[1].side, OrderSide.sell)
        assertEquals(account2.orders[1].type, OrderType.limit)
        assertEquals(account2.orders[1].price, 1.0)
        assertEquals(account2.orders[1].volume, 100.0)
        assertEquals(account2.orders[2].id, 3)
        assertEquals(account2.orders[2].symbol, "EURUSD")
        assertEquals(account2.orders[2].side, OrderSide.buy)
        assertEquals(account2.orders[2].type, OrderType.stop)
        assertEquals(account2.orders[2].price, 1.5)
        assertEquals(account2.orders[2].volume, 10.0)
    }

    @Test
    fun serializationJsonStructSimple()
    {
        // Define a source JSON string
        var json = """{"id":0,"f1":false,"f2":true,"f3":0,"f4":-1,"f5":0,"f6":33,"f7":0,"f8":1092,"f9":0,"f10":127,"f11":0,"f12":-1,"f13":0,"f14":32767,"f15":0,"f16":-1,"f17":0,"f18":2147483647,"f19":0,"f20":-1,"f21":0,"f22":9223372036854775807,"f23":0,"f24":-1,"f25":0.0,"f26":123.456,"f27":0.0,"f28":-1.23456e+125,"f29":"0","f30":"123456.123456","f31":"","f32":"Initial string!","f33":0,"f34":0,"f35":1543145597933463000,"f36":"00000000-0000-0000-0000-000000000000","f37":"e7854072-f0a5-11e8-8f69-ac220bcdd8e0","f38":"123e4567-e89b-12d3-a456-426655440000","f39":0,"f40":0,"f41":{"id":0,"symbol":"","side":0,"type":0,"price":0.0,"volume":0.0},"f42":{"currency":"","amount":0.0},"f43":0,"f44":{"id":0,"name":"","state":11,"wallet":{"currency":"","amount":0.0},"asset":null,"orders":[]}}"""

        // Create a new struct from the source JSON string
        val struct1 = StructSimple.fromJson(json)

        // Serialize the struct to the JSON string
        json = struct1.toJson()

        // Check the serialized JSON size
        assertTrue(json.isNotEmpty())

        // Deserialize the struct from the JSON string
        val struct2 = StructSimple.fromJson(json)

        assertEquals(struct2.f1, false)
        assertEquals(struct2.f2, true)
        assertEquals(struct2.f3, 0)
        assertEquals(struct2.f4, 0xFF.toByte())
        assertEquals(struct2.f5, '\u0000')
        assertEquals(struct2.f6, '!')
        assertEquals(struct2.f7, 0.toChar())
        assertEquals(struct2.f8, 0x0444.toChar())
        assertEquals(struct2.f9, 0)
        assertEquals(struct2.f10, 127)
        assertEquals(struct2.f11, 0u)
        assertEquals(struct2.f12, 0xFFu)
        assertEquals(struct2.f13, 0)
        assertEquals(struct2.f14, 32767)
        assertEquals(struct2.f15, 0u)
        assertEquals(struct2.f16, 0xFFFFu)
        assertEquals(struct2.f17, 0)
        assertEquals(struct2.f18, 2147483647)
        assertEquals(struct2.f19, 0u)
        assertEquals(struct2.f20, 0xFFFFFFFFu)
        assertEquals(struct2.f21, 0)
        assertEquals(struct2.f22, 9223372036854775807L)
        assertEquals(struct2.f23, 0u)
        assertEquals(struct2.f24, 0xFFFFFFFFFFFFFFFFuL)
        assertEquals(struct2.f25, 0.0f)
        assertTrue(Math.abs(struct2.f26 - 123.456f) < 0.0001)
        assertEquals(struct2.f27, 0.0)
        assertTrue(Math.abs(struct2.f28 - -123.567e+123) < 1e+123)
        assertEquals(struct2.f29, BigDecimal.valueOf(0))
        assertEquals(struct2.f30, BigDecimal.valueOf(123456.123456))
        assertEquals(struct2.f31, "")
        assertEquals(struct2.f32, "Initial string!")
        assertTrue(struct2.f33.epochSecond == 0L)
        assertTrue(struct2.f34.epochSecond == 0L)
        assertTrue(struct2.f35.epochSecond > GregorianCalendar(2018, 1, 1).toInstant().epochSecond)
        assertTrue(struct2.f36.compareTo(UUID(0, 0)) == 0)
        assertTrue(struct2.f37.compareTo(UUID(0, 0)) != 0)
        assertTrue(struct2.f38.compareTo(UUID.fromString("123e4567-e89b-12d3-a456-426655440000")) == 0)

        assertEquals(struct2.f1, struct1.f1)
        assertEquals(struct2.f2, struct1.f2)
        assertEquals(struct2.f3, struct1.f3)
        assertEquals(struct2.f4, struct1.f4)
        assertEquals(struct2.f5, struct1.f5)
        assertEquals(struct2.f6, struct1.f6)
        assertEquals(struct2.f7, struct1.f7)
        assertEquals(struct2.f8, struct1.f8)
        assertEquals(struct2.f9, struct1.f9)
        assertEquals(struct2.f10, struct1.f10)
        assertEquals(struct2.f11, struct1.f11)
        assertEquals(struct2.f12, struct1.f12)
        assertEquals(struct2.f13, struct1.f13)
        assertEquals(struct2.f14, struct1.f14)
        assertEquals(struct2.f15, struct1.f15)
        assertEquals(struct2.f16, struct1.f16)
        assertEquals(struct2.f17, struct1.f17)
        assertEquals(struct2.f18, struct1.f18)
        assertEquals(struct2.f19, struct1.f19)
        assertEquals(struct2.f20, struct1.f20)
        assertEquals(struct2.f21, struct1.f21)
        assertEquals(struct2.f22, struct1.f22)
        assertEquals(struct2.f23, struct1.f23)
        assertEquals(struct2.f24, struct1.f24)
        assertEquals(struct2.f25, struct1.f25)
        assertEquals(struct2.f26, struct1.f26)
        assertEquals(struct2.f27, struct1.f27)
        assertEquals(struct2.f28, struct1.f28)
        assertEquals(struct2.f29, struct1.f29)
        assertEquals(struct2.f30, struct1.f30)
        assertEquals(struct2.f31, struct1.f31)
        assertEquals(struct2.f32, struct1.f32)
        assertEquals(struct2.f33, struct1.f33)
        assertEquals(struct2.f34, struct1.f34)
        assertEquals(struct2.f35, struct1.f35)
        assertEquals(struct2.f36, struct1.f36)
        assertEquals(struct2.f37, struct1.f37)
        assertEquals(struct2.f38, struct1.f38)
        assertEquals(struct2.f39, struct1.f39)
        assertEquals(struct2.f40, struct1.f40)
    }

    @Test
    fun serializationJsonStructOptional()
    {
        // Define a source JSON string
        var json = """{"id":0,"f1":false,"f2":true,"f3":0,"f4":-1,"f5":0,"f6":33,"f7":0,"f8":1092,"f9":0,"f10":127,"f11":0,"f12":-1,"f13":0,"f14":32767,"f15":0,"f16":-1,"f17":0,"f18":2147483647,"f19":0,"f20":-1,"f21":0,"f22":9223372036854775807,"f23":0,"f24":-1,"f25":0.0,"f26":123.456,"f27":0.0,"f28":-1.23456e+125,"f29":"0","f30":"123456.123456","f31":"","f32":"Initial string!","f33":0,"f34":0,"f35":1543145860677797000,"f36":"00000000-0000-0000-0000-000000000000","f37":"8420d1c6-f0a6-11e8-80fc-ac220bcdd8e0","f38":"123e4567-e89b-12d3-a456-426655440000","f39":0,"f40":0,"f41":{"id":0,"symbol":"","side":0,"type":0,"price":0.0,"volume":0.0},"f42":{"currency":"","amount":0.0},"f43":0,"f44":{"id":0,"name":"","state":11,"wallet":{"currency":"","amount":0.0},"asset":null,"orders":[]},"f100":null,"f101":true,"f102":null,"f103":null,"f104":-1,"f105":null,"f106":null,"f107":33,"f108":null,"f109":null,"f110":1092,"f111":null,"f112":null,"f113":127,"f114":null,"f115":null,"f116":-1,"f117":null,"f118":null,"f119":32767,"f120":null,"f121":null,"f122":-1,"f123":null,"f124":null,"f125":2147483647,"f126":null,"f127":null,"f128":-1,"f129":null,"f130":null,"f131":9223372036854775807,"f132":null,"f133":null,"f134":-1,"f135":null,"f136":null,"f137":123.456,"f138":null,"f139":null,"f140":-1.23456e+125,"f141":null,"f142":null,"f143":"123456.123456","f144":null,"f145":null,"f146":"Initial string!","f147":null,"f148":null,"f149":1543145860678429000,"f150":null,"f151":null,"f152":"123e4567-e89b-12d3-a456-426655440000","f153":null,"f154":null,"f155":null,"f156":null,"f157":null,"f158":null,"f159":null,"f160":null,"f161":null,"f162":null,"f163":null,"f164":null,"f165":null}"""

        // Create a new struct from the source JSON string
        val struct1 = StructOptional.fromJson(json)

        // Serialize the struct to the JSON string
        json = struct1.toJson()

        // Check the serialized JSON size
        assertTrue(json.isNotEmpty())

        // Deserialize the struct from the JSON string
        val struct2 = StructOptional.fromJson(json)

        assertEquals(struct2.f1, false)
        assertEquals(struct2.f2, true)
        assertEquals(struct2.f3, 0)
        assertEquals(struct2.f4, 0xFF.toByte())
        assertEquals(struct2.f5, '\u0000')
        assertEquals(struct2.f6, '!')
        assertEquals(struct2.f7, 0.toChar())
        assertEquals(struct2.f8, 0x0444.toChar())
        assertEquals(struct2.f9, 0)
        assertEquals(struct2.f10, 127)
        assertEquals(struct2.f11, 0u)
        assertEquals(struct2.f12, 0xFFu)
        assertEquals(struct2.f13, 0)
        assertEquals(struct2.f14, 32767)
        assertEquals(struct2.f15, 0u)
        assertEquals(struct2.f16, 0xFFFFu)
        assertEquals(struct2.f17, 0)
        assertEquals(struct2.f18, 2147483647)
        assertEquals(struct2.f19, 0u)
        assertEquals(struct2.f20, 0xFFFFFFFFu)
        assertEquals(struct2.f21, 0)
        assertEquals(struct2.f22, 9223372036854775807L)
        assertEquals(struct2.f23, 0u)
        assertEquals(struct2.f24, 0xFFFFFFFFFFFFFFFFuL)
        assertEquals(struct2.f25, 0.0f)
        assertTrue(Math.abs(struct2.f26 - 123.456f) < 0.0001)
        assertEquals(struct2.f27, 0.0)
        assertTrue(Math.abs(struct2.f28 - -123.567e+123) < 1e+123)
        assertEquals(struct2.f29, BigDecimal.valueOf(0))
        assertEquals(struct2.f30, BigDecimal.valueOf(123456.123456))
        assertEquals(struct2.f31, "")
        assertEquals(struct2.f32, "Initial string!")
        assertTrue(struct2.f33.epochSecond == 0L)
        assertTrue(struct2.f34.epochSecond == 0L)
        assertTrue(struct2.f35.epochSecond > GregorianCalendar(2018, 1, 1).toInstant().epochSecond)
        assertTrue(struct2.f36.compareTo(UUID(0, 0)) == 0)
        assertTrue(struct2.f37.compareTo(UUID(0, 0)) != 0)
        assertTrue(struct2.f38.compareTo(UUID.fromString("123e4567-e89b-12d3-a456-426655440000")) == 0)

        assertEquals(struct2.f100, null)
        assertNotEquals(struct2.f101, null)
        assertEquals(struct2.f101!!, true)
        assertEquals(struct2.f102, null)
        assertEquals(struct2.f103, null)
        assertNotEquals(struct2.f104, null)
        assertEquals(struct2.f104!!, 0xFF.toByte())
        assertEquals(struct2.f105, null)
        assertEquals(struct2.f106, null)
        assertNotEquals(struct2.f107, null)
        assertEquals(struct2.f107!!, '!')
        assertEquals(struct2.f108, null)
        assertEquals(struct2.f109, null)
        assertNotEquals(struct2.f110, null)
        assertEquals(struct2.f110!!, 0x0444.toChar())
        assertEquals(struct2.f111, null)
        assertEquals(struct2.f112, null)
        assertNotEquals(struct2.f113, null)
        assertEquals(struct2.f113!!, 127)
        assertEquals(struct2.f114, null)
        assertEquals(struct2.f115, null)
        assertNotEquals(struct2.f116, null)
        assertEquals(struct2.f116!!, 0xFFu)
        assertEquals(struct2.f117, null)
        assertEquals(struct2.f118, null)
        assertNotEquals(struct2.f119, null)
        assertEquals(struct2.f119!!, 32767)
        assertEquals(struct2.f120, null)
        assertEquals(struct2.f121, null)
        assertNotEquals(struct2.f122, null)
        assertEquals(struct2.f122!!, 0xFFFFu)
        assertEquals(struct2.f123, null)
        assertEquals(struct2.f124, null)
        assertNotEquals(struct2.f125, null)
        assertEquals(struct2.f125!!, 2147483647)
        assertEquals(struct2.f126, null)
        assertEquals(struct2.f127, null)
        assertNotEquals(struct2.f128, null)
        assertEquals(struct2.f128!!, 0xFFFFFFFFu)
        assertEquals(struct2.f129, null)
        assertEquals(struct2.f130, null)
        assertNotEquals(struct2.f131, null)
        assertEquals(struct2.f131!!, 9223372036854775807L)
        assertEquals(struct2.f132, null)
        assertEquals(struct2.f133, null)
        assertNotEquals(struct2.f131, null)
        assertEquals(struct2.f134!!, 0xFFFFFFFFFFFFFFFFu)
        assertEquals(struct2.f135, null)
        assertEquals(struct2.f136, null)
        assertNotEquals(struct2.f137, null)
        assertTrue(Math.abs(struct2.f137!! - 123.456f) < 0.0001)
        assertEquals(struct2.f138, null)
        assertEquals(struct2.f139, null)
        assertNotEquals(struct2.f140, null)
        assertTrue(Math.abs(struct2.f140!! - -123.567e+123) < 1e+123)
        assertEquals(struct2.f141, null)
        assertEquals(struct2.f142, null)
        assertNotEquals(struct2.f143, null)
        assertEquals(struct2.f143, BigDecimal.valueOf(123456.123456))
        assertEquals(struct2.f144, null)
        assertEquals(struct2.f145, null)
        assertNotEquals(struct2.f146, null)
        assertEquals(struct2.f146, "Initial string!")
        assertEquals(struct2.f147, null)
        assertEquals(struct2.f148, null)
        assertNotEquals(struct2.f149, null)
        assertTrue(struct2.f149!!.epochSecond > GregorianCalendar(2018, 1, 1).toInstant().epochSecond)
        assertEquals(struct2.f150, null)
        assertEquals(struct2.f151, null)
        assertNotEquals(struct2.f152, null)
        assertTrue(struct2.f152!!.compareTo(UUID.fromString("123e4567-e89b-12d3-a456-426655440000")) == 0)
        assertEquals(struct2.f153, null)
        assertEquals(struct2.f154, null)
        assertEquals(struct2.f155, null)
        assertEquals(struct2.f156, null)
        assertEquals(struct2.f157, null)
        assertEquals(struct2.f158, null)
        assertEquals(struct2.f159, null)
        assertEquals(struct2.f160, null)
        assertEquals(struct2.f161, null)
        assertEquals(struct2.f162, null)
        assertEquals(struct2.f163, null)
        assertEquals(struct2.f164, null)
        assertEquals(struct2.f165, null)

        assertEquals(struct2.f1, struct1.f1)
        assertEquals(struct2.f2, struct1.f2)
        assertEquals(struct2.f3, struct1.f3)
        assertEquals(struct2.f4, struct1.f4)
        assertEquals(struct2.f5, struct1.f5)
        assertEquals(struct2.f6, struct1.f6)
        assertEquals(struct2.f7, struct1.f7)
        assertEquals(struct2.f8, struct1.f8)
        assertEquals(struct2.f9, struct1.f9)
        assertEquals(struct2.f10, struct1.f10)
        assertEquals(struct2.f11, struct1.f11)
        assertEquals(struct2.f12, struct1.f12)
        assertEquals(struct2.f13, struct1.f13)
        assertEquals(struct2.f14, struct1.f14)
        assertEquals(struct2.f15, struct1.f15)
        assertEquals(struct2.f16, struct1.f16)
        assertEquals(struct2.f17, struct1.f17)
        assertEquals(struct2.f18, struct1.f18)
        assertEquals(struct2.f19, struct1.f19)
        assertEquals(struct2.f20, struct1.f20)
        assertEquals(struct2.f21, struct1.f21)
        assertEquals(struct2.f22, struct1.f22)
        assertEquals(struct2.f23, struct1.f23)
        assertEquals(struct2.f24, struct1.f24)
        assertEquals(struct2.f25, struct1.f25)
        assertEquals(struct2.f26, struct1.f26)
        assertEquals(struct2.f27, struct1.f27)
        assertEquals(struct2.f28, struct1.f28)
        assertEquals(struct2.f29, struct1.f29)
        assertEquals(struct2.f30, struct1.f30)
        assertEquals(struct2.f31, struct1.f31)
        assertEquals(struct2.f32, struct1.f32)
        assertEquals(struct2.f33, struct1.f33)
        assertEquals(struct2.f34, struct1.f34)
        assertEquals(struct2.f35, struct1.f35)
        assertEquals(struct2.f36, struct1.f36)
        assertEquals(struct2.f37, struct1.f37)
        assertEquals(struct2.f38, struct1.f38)
        assertEquals(struct2.f39, struct1.f39)
        assertEquals(struct2.f40, struct1.f40)

        assertEquals(struct2.f100, struct1.f100)
        assertEquals(struct2.f101, struct1.f101)
        assertEquals(struct2.f102, struct1.f102)
        assertEquals(struct2.f103, struct1.f103)
        assertEquals(struct2.f104, struct1.f104)
        assertEquals(struct2.f105, struct1.f105)
        assertEquals(struct2.f106, struct1.f106)
        assertEquals(struct2.f107, struct1.f107)
        assertEquals(struct2.f108, struct1.f108)
        assertEquals(struct2.f109, struct1.f109)
        assertEquals(struct2.f110, struct1.f110)
        assertEquals(struct2.f111, struct1.f111)
        assertEquals(struct2.f112, struct1.f112)
        assertEquals(struct2.f113, struct1.f113)
        assertEquals(struct2.f114, struct1.f114)
        assertEquals(struct2.f115, struct1.f115)
        assertEquals(struct2.f116, struct1.f116)
        assertEquals(struct2.f117, struct1.f117)
        assertEquals(struct2.f118, struct1.f118)
        assertEquals(struct2.f119, struct1.f119)
        assertEquals(struct2.f120, struct1.f120)
        assertEquals(struct2.f121, struct1.f121)
        assertEquals(struct2.f122, struct1.f122)
        assertEquals(struct2.f123, struct1.f123)
        assertEquals(struct2.f124, struct1.f124)
        assertEquals(struct2.f125, struct1.f125)
        assertEquals(struct2.f126, struct1.f126)
        assertEquals(struct2.f127, struct1.f127)
        assertEquals(struct2.f128, struct1.f128)
        assertEquals(struct2.f129, struct1.f129)
        assertEquals(struct2.f130, struct1.f130)
        assertEquals(struct2.f131, struct1.f131)
        assertEquals(struct2.f132, struct1.f132)
        assertEquals(struct2.f133, struct1.f133)
        assertEquals(struct2.f134, struct1.f134)
        assertEquals(struct2.f135, struct1.f135)
        assertEquals(struct2.f136, struct1.f136)
        assertEquals(struct2.f137, struct1.f137)
        assertEquals(struct2.f138, struct1.f138)
        assertEquals(struct2.f139, struct1.f139)
        assertEquals(struct2.f140, struct1.f140)
        assertEquals(struct2.f141, struct1.f141)
        assertEquals(struct2.f142, struct1.f142)
        assertEquals(struct2.f143, struct1.f143)
        assertEquals(struct2.f144, struct1.f144)
        assertEquals(struct2.f145, struct1.f145)
        assertEquals(struct2.f146, struct1.f146)
        assertEquals(struct2.f147, struct1.f147)
        assertEquals(struct2.f148, struct1.f148)
        assertEquals(struct2.f149, struct1.f149)
        assertEquals(struct2.f150, struct1.f150)
        assertEquals(struct2.f151, struct1.f151)
        assertEquals(struct2.f152, struct1.f152)
        assertEquals(struct2.f153, struct1.f153)
        assertEquals(struct2.f154, struct1.f154)
        assertEquals(struct2.f155, struct1.f155)
        assertEquals(struct2.f156, struct1.f156)
        assertEquals(struct2.f157, struct1.f157)
    }

    @Test
    fun serializationJsonStructNested()
    {
        // Define a source JSON string
        var json = """{"id":0,"f1":false,"f2":true,"f3":0,"f4":-1,"f5":0,"f6":33,"f7":0,"f8":1092,"f9":0,"f10":127,"f11":0,"f12":-1,"f13":0,"f14":32767,"f15":0,"f16":-1,"f17":0,"f18":2147483647,"f19":0,"f20":-1,"f21":0,"f22":9223372036854775807,"f23":0,"f24":-1,"f25":0.0,"f26":123.456,"f27":0.0,"f28":-1.23456e+125,"f29":"0","f30":"123456.123456","f31":"","f32":"Initial string!","f33":0,"f34":0,"f35":1543145901646321000,"f36":"00000000-0000-0000-0000-000000000000","f37":"9c8c268e-f0a6-11e8-a777-ac220bcdd8e0","f38":"123e4567-e89b-12d3-a456-426655440000","f39":0,"f40":0,"f41":{"id":0,"symbol":"","side":0,"type":0,"price":0.0,"volume":0.0},"f42":{"currency":"","amount":0.0},"f43":0,"f44":{"id":0,"name":"","state":11,"wallet":{"currency":"","amount":0.0},"asset":null,"orders":[]},"f100":null,"f101":true,"f102":null,"f103":null,"f104":-1,"f105":null,"f106":null,"f107":33,"f108":null,"f109":null,"f110":1092,"f111":null,"f112":null,"f113":127,"f114":null,"f115":null,"f116":-1,"f117":null,"f118":null,"f119":32767,"f120":null,"f121":null,"f122":-1,"f123":null,"f124":null,"f125":2147483647,"f126":null,"f127":null,"f128":-1,"f129":null,"f130":null,"f131":9223372036854775807,"f132":null,"f133":null,"f134":-1,"f135":null,"f136":null,"f137":123.456,"f138":null,"f139":null,"f140":-1.23456e+125,"f141":null,"f142":null,"f143":"123456.123456","f144":null,"f145":null,"f146":"Initial string!","f147":null,"f148":null,"f149":1543145901647155000,"f150":null,"f151":null,"f152":"123e4567-e89b-12d3-a456-426655440000","f153":null,"f154":null,"f155":null,"f156":null,"f157":null,"f158":null,"f159":null,"f160":null,"f161":null,"f162":null,"f163":null,"f164":null,"f165":null,"f1000":0,"f1001":null,"f1002":50,"f1003":null,"f1004":0,"f1005":null,"f1006":42,"f1007":null,"f1008":{"id":0,"f1":false,"f2":true,"f3":0,"f4":-1,"f5":0,"f6":33,"f7":0,"f8":1092,"f9":0,"f10":127,"f11":0,"f12":-1,"f13":0,"f14":32767,"f15":0,"f16":-1,"f17":0,"f18":2147483647,"f19":0,"f20":-1,"f21":0,"f22":9223372036854775807,"f23":0,"f24":-1,"f25":0.0,"f26":123.456,"f27":0.0,"f28":-1.23456e+125,"f29":"0","f30":"123456.123456","f31":"","f32":"Initial string!","f33":0,"f34":0,"f35":1543145901647367000,"f36":"00000000-0000-0000-0000-000000000000","f37":"9c8c54c4-f0a6-11e8-a777-ac220bcdd8e0","f38":"123e4567-e89b-12d3-a456-426655440000","f39":0,"f40":0,"f41":{"id":0,"symbol":"","side":0,"type":0,"price":0.0,"volume":0.0},"f42":{"currency":"","amount":0.0},"f43":0,"f44":{"id":0,"name":"","state":11,"wallet":{"currency":"","amount":0.0},"asset":null,"orders":[]}},"f1009":null,"f1010":{"id":0,"f1":false,"f2":true,"f3":0,"f4":-1,"f5":0,"f6":33,"f7":0,"f8":1092,"f9":0,"f10":127,"f11":0,"f12":-1,"f13":0,"f14":32767,"f15":0,"f16":-1,"f17":0,"f18":2147483647,"f19":0,"f20":-1,"f21":0,"f22":9223372036854775807,"f23":0,"f24":-1,"f25":0.0,"f26":123.456,"f27":0.0,"f28":-1.23456e+125,"f29":"0","f30":"123456.123456","f31":"","f32":"Initial string!","f33":0,"f34":0,"f35":1543145901648310000,"f36":"00000000-0000-0000-0000-000000000000","f37":"9c8c6b76-f0a6-11e8-a777-ac220bcdd8e0","f38":"123e4567-e89b-12d3-a456-426655440000","f39":0,"f40":0,"f41":{"id":0,"symbol":"","side":0,"type":0,"price":0.0,"volume":0.0},"f42":{"currency":"","amount":0.0},"f43":0,"f44":{"id":0,"name":"","state":11,"wallet":{"currency":"","amount":0.0},"asset":null,"orders":[]},"f100":null,"f101":true,"f102":null,"f103":null,"f104":-1,"f105":null,"f106":null,"f107":33,"f108":null,"f109":null,"f110":1092,"f111":null,"f112":null,"f113":127,"f114":null,"f115":null,"f116":-1,"f117":null,"f118":null,"f119":32767,"f120":null,"f121":null,"f122":-1,"f123":null,"f124":null,"f125":2147483647,"f126":null,"f127":null,"f128":-1,"f129":null,"f130":null,"f131":9223372036854775807,"f132":null,"f133":null,"f134":-1,"f135":null,"f136":null,"f137":123.456,"f138":null,"f139":null,"f140":-1.23456e+125,"f141":null,"f142":null,"f143":"123456.123456","f144":null,"f145":null,"f146":"Initial string!","f147":null,"f148":null,"f149":1543145901648871000,"f150":null,"f151":null,"f152":"123e4567-e89b-12d3-a456-426655440000","f153":null,"f154":null,"f155":null,"f156":null,"f157":null,"f158":null,"f159":null,"f160":null,"f161":null,"f162":null,"f163":null,"f164":null,"f165":null},"f1011":null}"""

        // Create a new struct from the source JSON string
        val struct1 = StructNested.fromJson(json)

        // Serialize the struct to the JSON string
        json = struct1.toJson()

        // Check the serialized JSON size
        assertTrue(json.isNotEmpty())

        // Deserialize the struct from the JSON string
        val struct2 = StructNested.fromJson(json)

        assertEquals(struct2.f1, false)
        assertEquals(struct2.f2, true)
        assertEquals(struct2.f3, 0)
        assertEquals(struct2.f4, 0xFF.toByte())
        assertEquals(struct2.f5, '\u0000')
        assertEquals(struct2.f6, '!')
        assertEquals(struct2.f7, 0.toChar())
        assertEquals(struct2.f8, 0x0444.toChar())
        assertEquals(struct2.f9, 0)
        assertEquals(struct2.f10, 127)
        assertEquals(struct2.f11, 0u)
        assertEquals(struct2.f12, 0xFFu)
        assertEquals(struct2.f13, 0)
        assertEquals(struct2.f14, 32767)
        assertEquals(struct2.f15, 0u)
        assertEquals(struct2.f16, 0xFFFFu)
        assertEquals(struct2.f17, 0)
        assertEquals(struct2.f18, 2147483647)
        assertEquals(struct2.f19, 0u)
        assertEquals(struct2.f20, 0xFFFFFFFFu)
        assertEquals(struct2.f21, 0)
        assertEquals(struct2.f22, 9223372036854775807L)
        assertEquals(struct2.f23, 0u)
        assertEquals(struct2.f24, 0xFFFFFFFFFFFFFFFFuL)
        assertEquals(struct2.f25, 0.0f)
        assertTrue(Math.abs(struct2.f26 - 123.456f) < 0.0001)
        assertEquals(struct2.f27, 0.0)
        assertTrue(Math.abs(struct2.f28 - -123.567e+123) < 1e+123)
        assertEquals(struct2.f29, BigDecimal.valueOf(0))
        assertEquals(struct2.f30, BigDecimal.valueOf(123456.123456))
        assertEquals(struct2.f31, "")
        assertEquals(struct2.f32, "Initial string!")
        assertTrue(struct2.f33.epochSecond == 0L)
        assertTrue(struct2.f34.epochSecond == 0L)
        assertTrue(struct2.f35.epochSecond > GregorianCalendar(2018, 1, 1).toInstant().epochSecond)
        assertTrue(struct2.f36.compareTo(UUID(0, 0)) == 0)
        assertTrue(struct2.f37.compareTo(UUID(0, 0)) != 0)
        assertTrue(struct2.f38.compareTo(UUID.fromString("123e4567-e89b-12d3-a456-426655440000")) == 0)

        assertEquals(struct2.f100, null)
        assertNotEquals(struct2.f101, null)
        assertEquals(struct2.f101!!, true)
        assertEquals(struct2.f102, null)
        assertEquals(struct2.f103, null)
        assertNotEquals(struct2.f104, null)
        assertEquals(struct2.f104!!, 0xFF.toByte())
        assertEquals(struct2.f105, null)
        assertEquals(struct2.f106, null)
        assertNotEquals(struct2.f107, null)
        assertEquals(struct2.f107!!, '!')
        assertEquals(struct2.f108, null)
        assertEquals(struct2.f109, null)
        assertNotEquals(struct2.f110, null)
        assertEquals(struct2.f110!!, 0x0444.toChar())
        assertEquals(struct2.f111, null)
        assertEquals(struct2.f112, null)
        assertNotEquals(struct2.f113, null)
        assertEquals(struct2.f113!!, 127)
        assertEquals(struct2.f114, null)
        assertEquals(struct2.f115, null)
        assertNotEquals(struct2.f116, null)
        assertEquals(struct2.f116!!, 0xFFu)
        assertEquals(struct2.f117, null)
        assertEquals(struct2.f118, null)
        assertNotEquals(struct2.f119, null)
        assertEquals(struct2.f119!!, 32767)
        assertEquals(struct2.f120, null)
        assertEquals(struct2.f121, null)
        assertNotEquals(struct2.f122, null)
        assertEquals(struct2.f122!!, 0xFFFFu)
        assertEquals(struct2.f123, null)
        assertEquals(struct2.f124, null)
        assertNotEquals(struct2.f125, null)
        assertEquals(struct2.f125!!, 2147483647)
        assertEquals(struct2.f126, null)
        assertEquals(struct2.f127, null)
        assertNotEquals(struct2.f128, null)
        assertEquals(struct2.f128!!, 0xFFFFFFFFu)
        assertEquals(struct2.f129, null)
        assertEquals(struct2.f130, null)
        assertNotEquals(struct2.f131, null)
        assertEquals(struct2.f131!!, 9223372036854775807L)
        assertEquals(struct2.f132, null)
        assertEquals(struct2.f133, null)
        assertNotEquals(struct2.f131, null)
        assertEquals(struct2.f134!!, 0xFFFFFFFFFFFFFFFFu)
        assertEquals(struct2.f135, null)
        assertEquals(struct2.f136, null)
        assertNotEquals(struct2.f137, null)
        assertTrue(Math.abs(struct2.f137!! - 123.456f) < 0.0001)
        assertEquals(struct2.f138, null)
        assertEquals(struct2.f139, null)
        assertNotEquals(struct2.f140, null)
        assertTrue(Math.abs(struct2.f140!! - -123.567e+123) < 1e+123)
        assertEquals(struct2.f141, null)
        assertEquals(struct2.f142, null)
        assertNotEquals(struct2.f143, null)
        assertEquals(struct2.f143, BigDecimal.valueOf(123456.123456))
        assertEquals(struct2.f144, null)
        assertEquals(struct2.f145, null)
        assertNotEquals(struct2.f146, null)
        assertEquals(struct2.f146, "Initial string!")
        assertEquals(struct2.f147, null)
        assertEquals(struct2.f148, null)
        assertNotEquals(struct2.f149, null)
        assertTrue(struct2.f149!!.epochSecond > GregorianCalendar(2018, 1, 1).toInstant().epochSecond)
        assertEquals(struct2.f150, null)
        assertEquals(struct2.f151, null)
        assertNotEquals(struct2.f152, null)
        assertTrue(struct2.f152!!.compareTo(UUID.fromString("123e4567-e89b-12d3-a456-426655440000")) == 0)
        assertEquals(struct2.f153, null)
        assertEquals(struct2.f154, null)
        assertEquals(struct2.f155, null)
        assertEquals(struct2.f156, null)
        assertEquals(struct2.f157, null)
        assertEquals(struct2.f158, null)
        assertEquals(struct2.f159, null)
        assertEquals(struct2.f160, null)
        assertEquals(struct2.f161, null)
        assertEquals(struct2.f162, null)
        assertEquals(struct2.f163, null)
        assertEquals(struct2.f164, null)
        assertEquals(struct2.f165, null)

        assertEquals(struct2.f1000, EnumSimple.ENUM_VALUE_0)
        assertEquals(struct2.f1001, null)
        assertEquals(struct2.f1002, EnumTyped.ENUM_VALUE_2)
        assertEquals(struct2.f1003, null)
        assertEquals(struct2.f1004, FlagsSimple.FLAG_VALUE_0)
        assertEquals(struct2.f1005, null)
        assertEquals(struct2.f1006, FlagsTyped.fromSet(EnumSet.of(FlagsTyped.FLAG_VALUE_2.value, FlagsTyped.FLAG_VALUE_4.value, FlagsTyped.FLAG_VALUE_6.value)))
        assertEquals(struct2.f1007, null)
        assertEquals(struct2.f1009, null)
        assertEquals(struct2.f1011, null)

        assertEquals(struct2.f1, struct1.f1)
        assertEquals(struct2.f2, struct1.f2)
        assertEquals(struct2.f3, struct1.f3)
        assertEquals(struct2.f4, struct1.f4)
        assertEquals(struct2.f5, struct1.f5)
        assertEquals(struct2.f6, struct1.f6)
        assertEquals(struct2.f7, struct1.f7)
        assertEquals(struct2.f8, struct1.f8)
        assertEquals(struct2.f9, struct1.f9)
        assertEquals(struct2.f10, struct1.f10)
        assertEquals(struct2.f11, struct1.f11)
        assertEquals(struct2.f12, struct1.f12)
        assertEquals(struct2.f13, struct1.f13)
        assertEquals(struct2.f14, struct1.f14)
        assertEquals(struct2.f15, struct1.f15)
        assertEquals(struct2.f16, struct1.f16)
        assertEquals(struct2.f17, struct1.f17)
        assertEquals(struct2.f18, struct1.f18)
        assertEquals(struct2.f19, struct1.f19)
        assertEquals(struct2.f20, struct1.f20)
        assertEquals(struct2.f21, struct1.f21)
        assertEquals(struct2.f22, struct1.f22)
        assertEquals(struct2.f23, struct1.f23)
        assertEquals(struct2.f24, struct1.f24)
        assertEquals(struct2.f25, struct1.f25)
        assertEquals(struct2.f26, struct1.f26)
        assertEquals(struct2.f27, struct1.f27)
        assertEquals(struct2.f28, struct1.f28)
        assertEquals(struct2.f29, struct1.f29)
        assertEquals(struct2.f30, struct1.f30)
        assertEquals(struct2.f31, struct1.f31)
        assertEquals(struct2.f32, struct1.f32)
        assertEquals(struct2.f33, struct1.f33)
        assertEquals(struct2.f34, struct1.f34)
        assertEquals(struct2.f35, struct1.f35)
        assertEquals(struct2.f36, struct1.f36)
        assertEquals(struct2.f37, struct1.f37)
        assertEquals(struct2.f38, struct1.f38)
        assertEquals(struct2.f39, struct1.f39)
        assertEquals(struct2.f40, struct1.f40)

        assertEquals(struct2.f100, struct1.f100)
        assertEquals(struct2.f101, struct1.f101)
        assertEquals(struct2.f102, struct1.f102)
        assertEquals(struct2.f103, struct1.f103)
        assertEquals(struct2.f104, struct1.f104)
        assertEquals(struct2.f105, struct1.f105)
        assertEquals(struct2.f106, struct1.f106)
        assertEquals(struct2.f107, struct1.f107)
        assertEquals(struct2.f108, struct1.f108)
        assertEquals(struct2.f109, struct1.f109)
        assertEquals(struct2.f110, struct1.f110)
        assertEquals(struct2.f111, struct1.f111)
        assertEquals(struct2.f112, struct1.f112)
        assertEquals(struct2.f113, struct1.f113)
        assertEquals(struct2.f114, struct1.f114)
        assertEquals(struct2.f115, struct1.f115)
        assertEquals(struct2.f116, struct1.f116)
        assertEquals(struct2.f117, struct1.f117)
        assertEquals(struct2.f118, struct1.f118)
        assertEquals(struct2.f119, struct1.f119)
        assertEquals(struct2.f120, struct1.f120)
        assertEquals(struct2.f121, struct1.f121)
        assertEquals(struct2.f122, struct1.f122)
        assertEquals(struct2.f123, struct1.f123)
        assertEquals(struct2.f124, struct1.f124)
        assertEquals(struct2.f125, struct1.f125)
        assertEquals(struct2.f126, struct1.f126)
        assertEquals(struct2.f127, struct1.f127)
        assertEquals(struct2.f128, struct1.f128)
        assertEquals(struct2.f129, struct1.f129)
        assertEquals(struct2.f130, struct1.f130)
        assertEquals(struct2.f131, struct1.f131)
        assertEquals(struct2.f132, struct1.f132)
        assertEquals(struct2.f133, struct1.f133)
        assertEquals(struct2.f134, struct1.f134)
        assertEquals(struct2.f135, struct1.f135)
        assertEquals(struct2.f136, struct1.f136)
        assertEquals(struct2.f137, struct1.f137)
        assertEquals(struct2.f138, struct1.f138)
        assertEquals(struct2.f139, struct1.f139)
        assertEquals(struct2.f140, struct1.f140)
        assertEquals(struct2.f141, struct1.f141)
        assertEquals(struct2.f142, struct1.f142)
        assertEquals(struct2.f143, struct1.f143)
        assertEquals(struct2.f144, struct1.f144)
        assertEquals(struct2.f145, struct1.f145)
        assertEquals(struct2.f146, struct1.f146)
        assertEquals(struct2.f147, struct1.f147)
        assertEquals(struct2.f148, struct1.f148)
        assertEquals(struct2.f149, struct1.f149)
        assertEquals(struct2.f150, struct1.f150)
        assertEquals(struct2.f151, struct1.f151)
        assertEquals(struct2.f152, struct1.f152)
        assertEquals(struct2.f153, struct1.f153)
        assertEquals(struct2.f154, struct1.f154)
        assertEquals(struct2.f155, struct1.f155)
        assertEquals(struct2.f156, struct1.f156)
        assertEquals(struct2.f157, struct1.f157)

        assertEquals(struct2.f1000, struct1.f1000)
        assertEquals(struct2.f1001, struct1.f1001)
        assertEquals(struct2.f1002, struct1.f1002)
        assertEquals(struct2.f1003, struct1.f1003)
        assertEquals(struct2.f1004, struct1.f1004)
        assertEquals(struct2.f1005, struct1.f1005)
        assertEquals(struct2.f1006, struct1.f1006)
        assertEquals(struct2.f1007, struct1.f1007)
    }

    @Test
    fun serializationJsonStructBytes()
    {
        // Define a source JSON string
        var json = """{"f1":"QUJD","f2":"dGVzdA==","f3":null}"""

        // Create a new struct from the source JSON string
        val struct1 = StructBytes.fromJson(json)

        // Serialize the struct to the JSON string
        json = struct1.toJson()

        // Check the serialized JSON size
        assertTrue(json.isNotEmpty())

        // Deserialize the struct from the JSON string
        val struct2 = StructBytes.fromJson(json)

        assertEquals(struct2.f1.size, 3)
        assertEquals(struct2.f1[0], 'A'.code.toByte())
        assertEquals(struct2.f1[1], 'B'.code.toByte())
        assertEquals(struct2.f1[2], 'C'.code.toByte())
        assertNotEquals(struct2.f2, null)
        assertEquals(struct2.f2!!.size, 4)
        assertEquals(struct2.f2!![0], 't'.code.toByte())
        assertEquals(struct2.f2!![1], 'e'.code.toByte())
        assertEquals(struct2.f2!![2], 's'.code.toByte())
        assertEquals(struct2.f2!![3], 't'.code.toByte())
        assertEquals(struct2.f3, null)
    }

    @Test
    fun serializationJsonStructArray()
    {
        // Define a source JSON string
        var json = """{"f1":[48,65],"f2":[97,null],"f3":["MDAw","QUFB"],"f4":["YWFh",null],"f5":[1,2],"f6":[1,null],"f7":[3,7],"f8":[3,null],"f9":[{"id":0,"f1":false,"f2":true,"f3":0,"f4":-1,"f5":0,"f6":33,"f7":0,"f8":1092,"f9":0,"f10":127,"f11":0,"f12":-1,"f13":0,"f14":32767,"f15":0,"f16":-1,"f17":0,"f18":2147483647,"f19":0,"f20":-1,"f21":0,"f22":9223372036854775807,"f23":0,"f24":-1,"f25":0.0,"f26":123.456,"f27":0.0,"f28":-1.23456e+125,"f29":"0","f30":"123456.123456","f31":"","f32":"Initial string!","f33":0,"f34":0,"f35":1543145986060361000,"f36":"00000000-0000-0000-0000-000000000000","f37":"cedcad98-f0a6-11e8-9f47-ac220bcdd8e0","f38":"123e4567-e89b-12d3-a456-426655440000","f39":0,"f40":0,"f41":{"id":0,"symbol":"","side":0,"type":0,"price":0.0,"volume":0.0},"f42":{"currency":"","amount":0.0},"f43":0,"f44":{"id":0,"name":"","state":11,"wallet":{"currency":"","amount":0.0},"asset":null,"orders":[]}},{"id":0,"f1":false,"f2":true,"f3":0,"f4":-1,"f5":0,"f6":33,"f7":0,"f8":1092,"f9":0,"f10":127,"f11":0,"f12":-1,"f13":0,"f14":32767,"f15":0,"f16":-1,"f17":0,"f18":2147483647,"f19":0,"f20":-1,"f21":0,"f22":9223372036854775807,"f23":0,"f24":-1,"f25":0.0,"f26":123.456,"f27":0.0,"f28":-1.23456e+125,"f29":"0","f30":"123456.123456","f31":"","f32":"Initial string!","f33":0,"f34":0,"f35":1543145986060910000,"f36":"00000000-0000-0000-0000-000000000000","f37":"cedcc274-f0a6-11e8-9f47-ac220bcdd8e0","f38":"123e4567-e89b-12d3-a456-426655440000","f39":0,"f40":0,"f41":{"id":0,"symbol":"","side":0,"type":0,"price":0.0,"volume":0.0},"f42":{"currency":"","amount":0.0},"f43":0,"f44":{"id":0,"name":"","state":11,"wallet":{"currency":"","amount":0.0},"asset":null,"orders":[]}}],"f10":[{"id":0,"f1":false,"f2":true,"f3":0,"f4":-1,"f5":0,"f6":33,"f7":0,"f8":1092,"f9":0,"f10":127,"f11":0,"f12":-1,"f13":0,"f14":32767,"f15":0,"f16":-1,"f17":0,"f18":2147483647,"f19":0,"f20":-1,"f21":0,"f22":9223372036854775807,"f23":0,"f24":-1,"f25":0.0,"f26":123.456,"f27":0.0,"f28":-1.23456e+125,"f29":"0","f30":"123456.123456","f31":"","f32":"Initial string!","f33":0,"f34":0,"f35":1543145986061436000,"f36":"00000000-0000-0000-0000-000000000000","f37":"cedcd714-f0a6-11e8-9f47-ac220bcdd8e0","f38":"123e4567-e89b-12d3-a456-426655440000","f39":0,"f40":0,"f41":{"id":0,"symbol":"","side":0,"type":0,"price":0.0,"volume":0.0},"f42":{"currency":"","amount":0.0},"f43":0,"f44":{"id":0,"name":"","state":11,"wallet":{"currency":"","amount":0.0},"asset":null,"orders":[]}},null]}"""

        // Create a new struct from the source JSON string
        val struct1 = StructArray.fromJson(json)

        // Serialize the struct to the JSON string
        json = struct1.toJson()

        // Check the serialized JSON size
        assertTrue(json.isNotEmpty())

        // Deserialize the struct from the JSON string
        val struct2 = StructArray.fromJson(json)

        assertEquals(struct2.f1.size, 2)
        assertEquals(struct2.f1[0], 48)
        assertEquals(struct2.f1[1], 65)
        assertEquals(struct2.f2.size, 2)
        assertEquals(struct2.f2[0], 97)
        assertEquals(struct2.f2[1], null)
        assertEquals(struct2.f3.size, 2)
        assertEquals(struct2.f3[0].size, 3)
        assertEquals(struct2.f3[0][0].toInt(), 48)
        assertEquals(struct2.f3[0][1].toInt(), 48)
        assertEquals(struct2.f3[0][2].toInt(), 48)
        assertEquals(struct2.f3[1].size, 3)
        assertEquals(struct2.f3[1][0].toInt(), 65)
        assertEquals(struct2.f3[1][1].toInt(), 65)
        assertEquals(struct2.f3[1][2].toInt(), 65)
        assertEquals(struct2.f4.size, 2)
        assertNotEquals(struct2.f4[0], null)
        assertEquals(struct2.f4[0]!!.size, 3)
        assertEquals(struct2.f4[0]!![0].toInt(), 97)
        assertEquals(struct2.f4[0]!![1].toInt(), 97)
        assertEquals(struct2.f4[0]!![2].toInt(), 97)
        assertEquals(struct2.f4[1], null)
        assertEquals(struct2.f5.size, 2)
        assertEquals(struct2.f5[0], EnumSimple.ENUM_VALUE_1)
        assertEquals(struct2.f5[1], EnumSimple.ENUM_VALUE_2)
        assertEquals(struct2.f6.size, 2)
        assertEquals(struct2.f6[0], EnumSimple.ENUM_VALUE_1)
        assertEquals(struct2.f6[1], null)
        assertEquals(struct2.f7.size, 2)
        assertEquals(struct2.f7[0], FlagsSimple.fromSet(EnumSet.of(FlagsSimple.FLAG_VALUE_1.value, FlagsSimple.FLAG_VALUE_2.value)))
        assertEquals(struct2.f7[1], FlagsSimple.fromSet(EnumSet.of(FlagsSimple.FLAG_VALUE_1.value, FlagsSimple.FLAG_VALUE_2.value, FlagsSimple.FLAG_VALUE_3.value)))
        assertEquals(struct2.f8.size, 2)
        assertEquals(struct2.f8[0], FlagsSimple.fromSet(EnumSet.of(FlagsSimple.FLAG_VALUE_1.value, FlagsSimple.FLAG_VALUE_2.value)))
        assertEquals(struct2.f8[1], null)
        assertEquals(struct2.f9.size, 2)
        assertEquals(struct2.f9[0].f2, true)
        assertEquals(struct2.f9[0].f12, 0xFFu)
        assertEquals(struct2.f9[0].f32, "Initial string!")
        assertEquals(struct2.f9[1].f2, true)
        assertEquals(struct2.f9[1].f12, 0xFFu)
        assertEquals(struct2.f9[1].f32, "Initial string!")
        assertEquals(struct2.f10.size, 2)
        assertNotEquals(struct2.f10[0], null)
        assertEquals(struct2.f10[0]!!.f2, true)
        assertEquals(struct2.f10[0]!!.f12, 0xFFu)
        assertEquals(struct2.f10[0]!!.f32, "Initial string!")
        assertEquals(struct2.f10[1], null)
    }

    @Test
    fun serializationJsonStructVector()
    {
        // Define a source JSON string
        var json = """{"f1":[48,65],"f2":[97,null],"f3":["MDAw","QUFB"],"f4":["YWFh",null],"f5":[1,2],"f6":[1,null],"f7":[3,7],"f8":[3,null],"f9":[{"id":0,"f1":false,"f2":true,"f3":0,"f4":-1,"f5":0,"f6":33,"f7":0,"f8":1092,"f9":0,"f10":127,"f11":0,"f12":-1,"f13":0,"f14":32767,"f15":0,"f16":-1,"f17":0,"f18":2147483647,"f19":0,"f20":-1,"f21":0,"f22":9223372036854775807,"f23":0,"f24":-1,"f25":0.0,"f26":123.456,"f27":0.0,"f28":-1.23456e+125,"f29":"0","f30":"123456.123456","f31":"","f32":"Initial string!","f33":0,"f34":0,"f35":1543146157127964000,"f36":"00000000-0000-0000-0000-000000000000","f37":"34d38702-f0a7-11e8-b30e-ac220bcdd8e0","f38":"123e4567-e89b-12d3-a456-426655440000","f39":0,"f40":0,"f41":{"id":0,"symbol":"","side":0,"type":0,"price":0.0,"volume":0.0},"f42":{"currency":"","amount":0.0},"f43":0,"f44":{"id":0,"name":"","state":11,"wallet":{"currency":"","amount":0.0},"asset":null,"orders":[]}},{"id":0,"f1":false,"f2":true,"f3":0,"f4":-1,"f5":0,"f6":33,"f7":0,"f8":1092,"f9":0,"f10":127,"f11":0,"f12":-1,"f13":0,"f14":32767,"f15":0,"f16":-1,"f17":0,"f18":2147483647,"f19":0,"f20":-1,"f21":0,"f22":9223372036854775807,"f23":0,"f24":-1,"f25":0.0,"f26":123.456,"f27":0.0,"f28":-1.23456e+125,"f29":"0","f30":"123456.123456","f31":"","f32":"Initial string!","f33":0,"f34":0,"f35":1543146157128572000,"f36":"00000000-0000-0000-0000-000000000000","f37":"34d39c88-f0a7-11e8-b30e-ac220bcdd8e0","f38":"123e4567-e89b-12d3-a456-426655440000","f39":0,"f40":0,"f41":{"id":0,"symbol":"","side":0,"type":0,"price":0.0,"volume":0.0},"f42":{"currency":"","amount":0.0},"f43":0,"f44":{"id":0,"name":"","state":11,"wallet":{"currency":"","amount":0.0},"asset":null,"orders":[]}}],"f10":[{"id":0,"f1":false,"f2":true,"f3":0,"f4":-1,"f5":0,"f6":33,"f7":0,"f8":1092,"f9":0,"f10":127,"f11":0,"f12":-1,"f13":0,"f14":32767,"f15":0,"f16":-1,"f17":0,"f18":2147483647,"f19":0,"f20":-1,"f21":0,"f22":9223372036854775807,"f23":0,"f24":-1,"f25":0.0,"f26":123.456,"f27":0.0,"f28":-1.23456e+125,"f29":"0","f30":"123456.123456","f31":"","f32":"Initial string!","f33":0,"f34":0,"f35":1543146157129063000,"f36":"00000000-0000-0000-0000-000000000000","f37":"34d3b038-f0a7-11e8-b30e-ac220bcdd8e0","f38":"123e4567-e89b-12d3-a456-426655440000","f39":0,"f40":0,"f41":{"id":0,"symbol":"","side":0,"type":0,"price":0.0,"volume":0.0},"f42":{"currency":"","amount":0.0},"f43":0,"f44":{"id":0,"name":"","state":11,"wallet":{"currency":"","amount":0.0},"asset":null,"orders":[]}},null]}"""

        // Create a new struct from the source JSON string
        val struct1 = StructVector.fromJson(json)

        // Serialize the struct to the JSON string
        json = struct1.toJson()

        // Check the serialized JSON size
        assertTrue(json.isNotEmpty())

        // Deserialize the struct from the JSON string
        val struct2 = StructVector.fromJson(json)

        assertEquals(struct2.f1.size, 2)
        assertEquals(struct2.f1[0].toInt(), 48)
        assertEquals(struct2.f1[1].toInt(), 65)
        assertEquals(struct2.f2.size, 2)
        assertEquals(struct2.f2[0], 97)
        assertEquals(struct2.f2[1], null)
        assertEquals(struct2.f3.size, 2)
        assertEquals(struct2.f3[0].size, 3)
        assertEquals(struct2.f3[0][0].toInt(), 48)
        assertEquals(struct2.f3[0][1].toInt(), 48)
        assertEquals(struct2.f3[0][2].toInt(), 48)
        assertEquals(struct2.f3[1].size, 3)
        assertEquals(struct2.f3[1][0].toInt(), 65)
        assertEquals(struct2.f3[1][1].toInt(), 65)
        assertEquals(struct2.f3[1][2].toInt(), 65)
        assertEquals(struct2.f4.size, 2)
        assertNotEquals(struct2.f4[0], null)
        assertEquals(struct2.f4[0]!!.size, 3)
        assertEquals(struct2.f4[0]!![0].toInt(), 97)
        assertEquals(struct2.f4[0]!![1].toInt(), 97)
        assertEquals(struct2.f4[0]!![2].toInt(), 97)
        assertEquals(struct2.f4[1], null)
        assertEquals(struct2.f5.size, 2)
        assertEquals(struct2.f5[0], EnumSimple.ENUM_VALUE_1)
        assertEquals(struct2.f5[1], EnumSimple.ENUM_VALUE_2)
        assertEquals(struct2.f6.size, 2)
        assertEquals(struct2.f6[0], EnumSimple.ENUM_VALUE_1)
        assertEquals(struct2.f6[1], null)
        assertEquals(struct2.f7.size, 2)
        assertEquals(struct2.f7[0], FlagsSimple.fromSet(EnumSet.of(FlagsSimple.FLAG_VALUE_1.value, FlagsSimple.FLAG_VALUE_2.value)))
        assertEquals(struct2.f7[1], FlagsSimple.fromSet(EnumSet.of(FlagsSimple.FLAG_VALUE_1.value, FlagsSimple.FLAG_VALUE_2.value, FlagsSimple.FLAG_VALUE_3.value)))
        assertEquals(struct2.f8.size, 2)
        assertEquals(struct2.f8[0], FlagsSimple.fromSet(EnumSet.of(FlagsSimple.FLAG_VALUE_1.value, FlagsSimple.FLAG_VALUE_2.value)))
        assertEquals(struct2.f8[1], null)
        assertEquals(struct2.f9.size, 2)
        assertEquals(struct2.f9[0].f2, true)
        assertEquals(struct2.f9[0].f12, 0xFFu)
        assertEquals(struct2.f9[0].f32, "Initial string!")
        assertEquals(struct2.f9[1].f2, true)
        assertEquals(struct2.f9[1].f12, 0xFFu)
        assertEquals(struct2.f9[1].f32, "Initial string!")
        assertEquals(struct2.f10.size, 2)
        assertNotEquals(struct2.f10[0], null)
        assertEquals(struct2.f10[0]!!.f2, true)
        assertEquals(struct2.f10[0]!!.f12, 0xFFu)
        assertEquals(struct2.f10[0]!!.f32, "Initial string!")
        assertEquals(struct2.f10[1], null)
    }

    @Test
    fun serializationJsonStructList()
    {
        // Define a source JSON string
        var json = """{"f1":[48,65],"f2":[97,null],"f3":["MDAw","QUFB"],"f4":["YWFh",null],"f5":[1,2],"f6":[1,null],"f7":[3,7],"f8":[3,null],"f9":[{"id":0,"f1":false,"f2":true,"f3":0,"f4":-1,"f5":0,"f6":33,"f7":0,"f8":1092,"f9":0,"f10":127,"f11":0,"f12":-1,"f13":0,"f14":32767,"f15":0,"f16":-1,"f17":0,"f18":2147483647,"f19":0,"f20":-1,"f21":0,"f22":9223372036854775807,"f23":0,"f24":-1,"f25":0.0,"f26":123.456,"f27":0.0,"f28":-1.23456e+125,"f29":"0","f30":"123456.123456","f31":"","f32":"Initial string!","f33":0,"f34":0,"f35":1543146220253760000,"f36":"00000000-0000-0000-0000-000000000000","f37":"5a73e7fe-f0a7-11e8-89e6-ac220bcdd8e0","f38":"123e4567-e89b-12d3-a456-426655440000","f39":0,"f40":0,"f41":{"id":0,"symbol":"","side":0,"type":0,"price":0.0,"volume":0.0},"f42":{"currency":"","amount":0.0},"f43":0,"f44":{"id":0,"name":"","state":11,"wallet":{"currency":"","amount":0.0},"asset":null,"orders":[]}},{"id":0,"f1":false,"f2":true,"f3":0,"f4":-1,"f5":0,"f6":33,"f7":0,"f8":1092,"f9":0,"f10":127,"f11":0,"f12":-1,"f13":0,"f14":32767,"f15":0,"f16":-1,"f17":0,"f18":2147483647,"f19":0,"f20":-1,"f21":0,"f22":9223372036854775807,"f23":0,"f24":-1,"f25":0.0,"f26":123.456,"f27":0.0,"f28":-1.23456e+125,"f29":"0","f30":"123456.123456","f31":"","f32":"Initial string!","f33":0,"f34":0,"f35":1543146220255725000,"f36":"00000000-0000-0000-0000-000000000000","f37":"5a741990-f0a7-11e8-89e6-ac220bcdd8e0","f38":"123e4567-e89b-12d3-a456-426655440000","f39":0,"f40":0,"f41":{"id":0,"symbol":"","side":0,"type":0,"price":0.0,"volume":0.0},"f42":{"currency":"","amount":0.0},"f43":0,"f44":{"id":0,"name":"","state":11,"wallet":{"currency":"","amount":0.0},"asset":null,"orders":[]}}],"f10":[{"id":0,"f1":false,"f2":true,"f3":0,"f4":-1,"f5":0,"f6":33,"f7":0,"f8":1092,"f9":0,"f10":127,"f11":0,"f12":-1,"f13":0,"f14":32767,"f15":0,"f16":-1,"f17":0,"f18":2147483647,"f19":0,"f20":-1,"f21":0,"f22":9223372036854775807,"f23":0,"f24":-1,"f25":0.0,"f26":123.456,"f27":0.0,"f28":-1.23456e+125,"f29":"0","f30":"123456.123456","f31":"","f32":"Initial string!","f33":0,"f34":0,"f35":1543146220256802000,"f36":"00000000-0000-0000-0000-000000000000","f37":"5a74e4b0-f0a7-11e8-89e6-ac220bcdd8e0","f38":"123e4567-e89b-12d3-a456-426655440000","f39":0,"f40":0,"f41":{"id":0,"symbol":"","side":0,"type":0,"price":0.0,"volume":0.0},"f42":{"currency":"","amount":0.0},"f43":0,"f44":{"id":0,"name":"","state":11,"wallet":{"currency":"","amount":0.0},"asset":null,"orders":[]}},null]}"""

        // Create a new struct from the source JSON string
        val struct1 = StructList.fromJson(json)

        // Serialize the struct to the JSON string
        json = struct1.toJson()

        // Check the serialized JSON size
        assertTrue(json.isNotEmpty())

        // Deserialize the struct from the JSON string
        val struct2 = StructList.fromJson(json)

        assertEquals(struct2.f1.size, 2)
        assertEquals(struct2.f1.first.toByte().toInt(), 48)
        assertEquals(struct2.f1.last.toByte().toInt(), 65)
        assertEquals(struct2.f2.size, 2)
        assertEquals(struct2.f2.first!!.toByte().toInt(), 97)
        assertEquals(struct2.f2.last, null)
        assertEquals(struct2.f3.size, 2)
        assertEquals(struct2.f3.first.size, 3)
        assertEquals(struct2.f3.first[0].toInt(), 48)
        assertEquals(struct2.f3.first[1].toInt(), 48)
        assertEquals(struct2.f3.first[2].toInt(), 48)
        assertEquals(struct2.f3.last.size, 3)
        assertEquals(struct2.f3.last[0].toInt(), 65)
        assertEquals(struct2.f3.last[1].toInt(), 65)
        assertEquals(struct2.f3.last[2].toInt(), 65)
        assertEquals(struct2.f4.size, 2)
        assertNotEquals(struct2.f4.first, null)
        assertEquals(struct2.f4.first!!.size, 3)
        assertEquals(struct2.f4.first!![0].toInt(), 97)
        assertEquals(struct2.f4.first!![1].toInt(), 97)
        assertEquals(struct2.f4.first!![2].toInt(), 97)
        assertEquals(struct2.f4.last, null)
        assertEquals(struct2.f5.size, 2)
        assertEquals(struct2.f5.first, EnumSimple.ENUM_VALUE_1)
        assertEquals(struct2.f5.last, EnumSimple.ENUM_VALUE_2)
        assertEquals(struct2.f6.size, 2)
        assertEquals(struct2.f6.first, EnumSimple.ENUM_VALUE_1)
        assertEquals(struct2.f6.last, null)
        assertEquals(struct2.f7.size, 2)
        assertEquals(struct2.f7.first, FlagsSimple.fromSet(EnumSet.of(FlagsSimple.FLAG_VALUE_1.value, FlagsSimple.FLAG_VALUE_2.value)))
        assertEquals(struct2.f7.last, FlagsSimple.fromSet(EnumSet.of(FlagsSimple.FLAG_VALUE_1.value, FlagsSimple.FLAG_VALUE_2.value, FlagsSimple.FLAG_VALUE_3.value)))
        assertEquals(struct2.f8.size, 2)
        assertEquals(struct2.f8.first, FlagsSimple.fromSet(EnumSet.of(FlagsSimple.FLAG_VALUE_1.value, FlagsSimple.FLAG_VALUE_2.value)))
        assertEquals(struct2.f8.last, null)
        assertEquals(struct2.f9.size, 2)
        assertEquals(struct2.f9.first.f2, true)
        assertEquals(struct2.f9.first.f12, 0xFFu)
        assertEquals(struct2.f9.first.f32, "Initial string!")
        assertEquals(struct2.f9.last.f2, true)
        assertEquals(struct2.f9.last.f12, 0xFFu)
        assertEquals(struct2.f9.last.f32, "Initial string!")
        assertEquals(struct2.f10.size, 2)
        assertNotEquals(struct2.f10.first, null)
        assertEquals(struct2.f10.first!!.f2, true)
        assertEquals(struct2.f10.first!!.f12, 0xFFu)
        assertEquals(struct2.f10.first!!.f32, "Initial string!")
        assertEquals(struct2.f10.last, null)
    }

    @Test
    fun serializationJsonStructSet()
    {
        // Define a source JSON string
        var json = """{"f1":[48,65,97],"f2":[1,2],"f3":[3,7],"f4":[{"id":48,"f1":false,"f2":true,"f3":0,"f4":-1,"f5":0,"f6":33,"f7":0,"f8":1092,"f9":0,"f10":127,"f11":0,"f12":-1,"f13":0,"f14":32767,"f15":0,"f16":-1,"f17":0,"f18":2147483647,"f19":0,"f20":-1,"f21":0,"f22":9223372036854775807,"f23":0,"f24":-1,"f25":0.0,"f26":123.456,"f27":0.0,"f28":-1.23456e+125,"f29":"0","f30":"123456.123456","f31":"","f32":"Initial string!","f33":0,"f34":0,"f35":1543146299848353000,"f36":"00000000-0000-0000-0000-000000000000","f37":"89e4edd0-f0a7-11e8-9dde-ac220bcdd8e0","f38":"123e4567-e89b-12d3-a456-426655440000","f39":0,"f40":0,"f41":{"id":0,"symbol":"","side":0,"type":0,"price":0.0,"volume":0.0},"f42":{"currency":"","amount":0.0},"f43":0,"f44":{"id":0,"name":"","state":11,"wallet":{"currency":"","amount":0.0},"asset":null,"orders":[]}},{"id":65,"f1":false,"f2":true,"f3":0,"f4":-1,"f5":0,"f6":33,"f7":0,"f8":1092,"f9":0,"f10":127,"f11":0,"f12":-1,"f13":0,"f14":32767,"f15":0,"f16":-1,"f17":0,"f18":2147483647,"f19":0,"f20":-1,"f21":0,"f22":9223372036854775807,"f23":0,"f24":-1,"f25":0.0,"f26":123.456,"f27":0.0,"f28":-1.23456e+125,"f29":"0","f30":"123456.123456","f31":"","f32":"Initial string!","f33":0,"f34":0,"f35":1543146299848966000,"f36":"00000000-0000-0000-0000-000000000000","f37":"89e503f6-f0a7-11e8-9dde-ac220bcdd8e0","f38":"123e4567-e89b-12d3-a456-426655440000","f39":0,"f40":0,"f41":{"id":0,"symbol":"","side":0,"type":0,"price":0.0,"volume":0.0},"f42":{"currency":"","amount":0.0},"f43":0,"f44":{"id":0,"name":"","state":11,"wallet":{"currency":"","amount":0.0},"asset":null,"orders":[]}}]}"""

        // Create a new struct from the source JSON string
        val struct1 = StructSet.fromJson(json)

        // Serialize the struct to the JSON string
        json = struct1.toJson()

        // Check the serialized JSON size
        assertTrue(json.isNotEmpty())

        // Deserialize the struct from the JSON string
        val struct2 = StructSet.fromJson(json)

        assertEquals(struct2.f1.size, 3)
        assertTrue(struct2.f1.contains(48.toByte()))
        assertTrue(struct2.f1.contains(65.toByte()))
        assertTrue(struct2.f1.contains(97.toByte()))
        assertEquals(struct2.f2.size, 2)
        assertTrue(struct2.f2.contains(EnumSimple.ENUM_VALUE_1))
        assertTrue(struct2.f2.contains(EnumSimple.ENUM_VALUE_2))
        assertEquals(struct2.f3.size, 2)
        assertTrue(struct2.f3.contains(FlagsSimple.fromSet(EnumSet.of(FlagsSimple.FLAG_VALUE_1.value, FlagsSimple.FLAG_VALUE_2.value))))
        assertTrue(struct2.f3.contains(FlagsSimple.fromSet(EnumSet.of(FlagsSimple.FLAG_VALUE_1.value, FlagsSimple.FLAG_VALUE_2.value, FlagsSimple.FLAG_VALUE_3.value))))
        assertEquals(struct2.f4.size, 2)
        val s1 = StructSimple()
        s1.id = 48
        assertTrue(struct2.f4.contains(s1))
        val s2 = StructSimple()
        s2.id = 65
        assertTrue(struct2.f4.contains(s2))
    }

    @Test
    fun serializationJsonStructMap()
    {
        // Define a source JSON string
        var json = """{"f1":{"10":48,"20":65},"f2":{"10":97,"20":null},"f3":{"10":"MDAw","20":"QUFB"},"f4":{"10":"YWFh","20":null},"f5":{"10":1,"20":2},"f6":{"10":1,"20":null},"f7":{"10":3,"20":7},"f8":{"10":3,"20":null},"f9":{"10":{"id":48,"f1":false,"f2":true,"f3":0,"f4":-1,"f5":0,"f6":33,"f7":0,"f8":1092,"f9":0,"f10":127,"f11":0,"f12":-1,"f13":0,"f14":32767,"f15":0,"f16":-1,"f17":0,"f18":2147483647,"f19":0,"f20":-1,"f21":0,"f22":9223372036854775807,"f23":0,"f24":-1,"f25":0.0,"f26":123.456,"f27":0.0,"f28":-1.23456e+125,"f29":"0","f30":"123456.123456","f31":"","f32":"Initial string!","f33":0,"f34":0,"f35":1543146345803483000,"f36":"00000000-0000-0000-0000-000000000000","f37":"a549215e-f0a7-11e8-90f6-ac220bcdd8e0","f38":"123e4567-e89b-12d3-a456-426655440000","f39":0,"f40":0,"f41":{"id":0,"symbol":"","side":0,"type":0,"price":0.0,"volume":0.0},"f42":{"currency":"","amount":0.0},"f43":0,"f44":{"id":0,"name":"","state":11,"wallet":{"currency":"","amount":0.0},"asset":null,"orders":[]}},"20":{"id":65,"f1":false,"f2":true,"f3":0,"f4":-1,"f5":0,"f6":33,"f7":0,"f8":1092,"f9":0,"f10":127,"f11":0,"f12":-1,"f13":0,"f14":32767,"f15":0,"f16":-1,"f17":0,"f18":2147483647,"f19":0,"f20":-1,"f21":0,"f22":9223372036854775807,"f23":0,"f24":-1,"f25":0.0,"f26":123.456,"f27":0.0,"f28":-1.23456e+125,"f29":"0","f30":"123456.123456","f31":"","f32":"Initial string!","f33":0,"f34":0,"f35":1543146345804184000,"f36":"00000000-0000-0000-0000-000000000000","f37":"a54942ce-f0a7-11e8-90f6-ac220bcdd8e0","f38":"123e4567-e89b-12d3-a456-426655440000","f39":0,"f40":0,"f41":{"id":0,"symbol":"","side":0,"type":0,"price":0.0,"volume":0.0},"f42":{"currency":"","amount":0.0},"f43":0,"f44":{"id":0,"name":"","state":11,"wallet":{"currency":"","amount":0.0},"asset":null,"orders":[]}}},"f10":{"10":{"id":48,"f1":false,"f2":true,"f3":0,"f4":-1,"f5":0,"f6":33,"f7":0,"f8":1092,"f9":0,"f10":127,"f11":0,"f12":-1,"f13":0,"f14":32767,"f15":0,"f16":-1,"f17":0,"f18":2147483647,"f19":0,"f20":-1,"f21":0,"f22":9223372036854775807,"f23":0,"f24":-1,"f25":0.0,"f26":123.456,"f27":0.0,"f28":-1.23456e+125,"f29":"0","f30":"123456.123456","f31":"","f32":"Initial string!","f33":0,"f34":0,"f35":1543146345803483000,"f36":"00000000-0000-0000-0000-000000000000","f37":"a549215e-f0a7-11e8-90f6-ac220bcdd8e0","f38":"123e4567-e89b-12d3-a456-426655440000","f39":0,"f40":0,"f41":{"id":0,"symbol":"","side":0,"type":0,"price":0.0,"volume":0.0},"f42":{"currency":"","amount":0.0},"f43":0,"f44":{"id":0,"name":"","state":11,"wallet":{"currency":"","amount":0.0},"asset":null,"orders":[]}},"20":null}}"""

        // Create a new struct from the source JSON string
        val struct1 = StructMap.fromJson(json)

        // Serialize the struct to the JSON string
        json = struct1.toJson()

        // Check the serialized JSON size
        assertTrue(json.isNotEmpty())

        // Deserialize the struct from the JSON string
        val struct2 = StructMap.fromJson(json)

        assertEquals(struct2.f1.size, 2)
        assertEquals(struct2.f1[10]!!.toByte().toInt(), 48)
        assertEquals(struct2.f1[20]!!.toByte().toInt(), 65)
        assertEquals(struct2.f2.size, 2)
        assertEquals(struct2.f2[10]!!.toByte().toInt(), 97)
        assertEquals(struct2.f2[20], null)
        assertEquals(struct2.f3.size, 2)
        assertEquals(struct2.f3[10]!!.size, 3)
        assertEquals(struct2.f3[20]!!.size, 3)
        assertEquals(struct2.f4.size, 2)
        assertEquals(struct2.f4[10]!!.size, 3)
        assertEquals(struct2.f4[20], null)
        assertEquals(struct2.f5.size, 2)
        assertEquals(struct2.f5[10], EnumSimple.ENUM_VALUE_1)
        assertEquals(struct2.f5[20], EnumSimple.ENUM_VALUE_2)
        assertEquals(struct2.f6.size, 2)
        assertEquals(struct2.f6[10], EnumSimple.ENUM_VALUE_1)
        assertEquals(struct2.f6[20], null)
        assertEquals(struct2.f7.size, 2)
        assertEquals(struct2.f7[10], FlagsSimple.fromSet(EnumSet.of(FlagsSimple.FLAG_VALUE_1.value, FlagsSimple.FLAG_VALUE_2.value)))
        assertEquals(struct2.f7[20], FlagsSimple.fromSet(EnumSet.of(FlagsSimple.FLAG_VALUE_1.value, FlagsSimple.FLAG_VALUE_2.value, FlagsSimple.FLAG_VALUE_3.value)))
        assertEquals(struct2.f8.size, 2)
        assertEquals(struct2.f8[10], FlagsSimple.fromSet(EnumSet.of(FlagsSimple.FLAG_VALUE_1.value, FlagsSimple.FLAG_VALUE_2.value)))
        assertEquals(struct2.f8[20], null)
        assertEquals(struct2.f9.size, 2)
        assertEquals(struct2.f9[10]!!.id, 48)
        assertEquals(struct2.f9[20]!!.id, 65)
        assertEquals(struct2.f10.size, 2)
        assertEquals(struct2.f10[10]!!.id, 48)
        assertEquals(struct2.f10[20], null)
    }

    @Test
    fun serializationJsonStructHash()
    {
        // Define a source JSON string
        var json = """{"f1":{"10":48,"20":65},"f2":{"10":97,"20":null},"f3":{"10":"MDAw","20":"QUFB"},"f4":{"10":"YWFh","20":null},"f5":{"10":1,"20":2},"f6":{"10":1,"20":null},"f7":{"10":3,"20":7},"f8":{"10":3,"20":null},"f9":{"10":{"id":48,"f1":false,"f2":true,"f3":0,"f4":-1,"f5":0,"f6":33,"f7":0,"f8":1092,"f9":0,"f10":127,"f11":0,"f12":-1,"f13":0,"f14":32767,"f15":0,"f16":-1,"f17":0,"f18":2147483647,"f19":0,"f20":-1,"f21":0,"f22":9223372036854775807,"f23":0,"f24":-1,"f25":0.0,"f26":123.456,"f27":0.0,"f28":-1.23456e+125,"f29":"0","f30":"123456.123456","f31":"","f32":"Initial string!","f33":0,"f34":0,"f35":1543146381450913000,"f36":"00000000-0000-0000-0000-000000000000","f37":"ba8885d2-f0a7-11e8-81fa-ac220bcdd8e0","f38":"123e4567-e89b-12d3-a456-426655440000","f39":0,"f40":0,"f41":{"id":0,"symbol":"","side":0,"type":0,"price":0.0,"volume":0.0},"f42":{"currency":"","amount":0.0},"f43":0,"f44":{"id":0,"name":"","state":11,"wallet":{"currency":"","amount":0.0},"asset":null,"orders":[]}},"20":{"id":65,"f1":false,"f2":true,"f3":0,"f4":-1,"f5":0,"f6":33,"f7":0,"f8":1092,"f9":0,"f10":127,"f11":0,"f12":-1,"f13":0,"f14":32767,"f15":0,"f16":-1,"f17":0,"f18":2147483647,"f19":0,"f20":-1,"f21":0,"f22":9223372036854775807,"f23":0,"f24":-1,"f25":0.0,"f26":123.456,"f27":0.0,"f28":-1.23456e+125,"f29":"0","f30":"123456.123456","f31":"","f32":"Initial string!","f33":0,"f34":0,"f35":1543146381452825000,"f36":"00000000-0000-0000-0000-000000000000","f37":"ba88ced4-f0a7-11e8-81fa-ac220bcdd8e0","f38":"123e4567-e89b-12d3-a456-426655440000","f39":0,"f40":0,"f41":{"id":0,"symbol":"","side":0,"type":0,"price":0.0,"volume":0.0},"f42":{"currency":"","amount":0.0},"f43":0,"f44":{"id":0,"name":"","state":11,"wallet":{"currency":"","amount":0.0},"asset":null,"orders":[]}}},"f10":{"10":{"id":48,"f1":false,"f2":true,"f3":0,"f4":-1,"f5":0,"f6":33,"f7":0,"f8":1092,"f9":0,"f10":127,"f11":0,"f12":-1,"f13":0,"f14":32767,"f15":0,"f16":-1,"f17":0,"f18":2147483647,"f19":0,"f20":-1,"f21":0,"f22":9223372036854775807,"f23":0,"f24":-1,"f25":0.0,"f26":123.456,"f27":0.0,"f28":-1.23456e+125,"f29":"0","f30":"123456.123456","f31":"","f32":"Initial string!","f33":0,"f34":0,"f35":1543146381450913000,"f36":"00000000-0000-0000-0000-000000000000","f37":"ba8885d2-f0a7-11e8-81fa-ac220bcdd8e0","f38":"123e4567-e89b-12d3-a456-426655440000","f39":0,"f40":0,"f41":{"id":0,"symbol":"","side":0,"type":0,"price":0.0,"volume":0.0},"f42":{"currency":"","amount":0.0},"f43":0,"f44":{"id":0,"name":"","state":11,"wallet":{"currency":"","amount":0.0},"asset":null,"orders":[]}},"20":null}}"""

        // Create a new struct from the source JSON string
        val struct1 = StructHash.fromJson(json)

        // Serialize the struct to the JSON string
        json = struct1.toJson()

        // Check the serialized JSON size
        assertTrue(json.isNotEmpty())

        // Deserialize the struct from the JSON string
        val struct2 = StructHash.fromJson(json)

        assertEquals(struct2.f1.size, 2)
        assertEquals(struct2.f1["10"]!!.toByte().toInt(), 48)
        assertEquals(struct2.f1["20"]!!.toByte().toInt(), 65)
        assertEquals(struct2.f2.size, 2)
        assertEquals(struct2.f2["10"]!!.toByte().toInt(), 97)
        assertEquals(struct2.f2["20"], null)
        assertEquals(struct2.f3.size, 2)
        assertEquals(struct2.f3["10"]!!.size, 3)
        assertEquals(struct2.f3["20"]!!.size, 3)
        assertEquals(struct2.f4.size, 2)
        assertEquals(struct2.f4["10"]!!.size, 3)
        assertEquals(struct2.f4["20"], null)
        assertEquals(struct2.f5.size, 2)
        assertEquals(struct2.f5["10"], EnumSimple.ENUM_VALUE_1)
        assertEquals(struct2.f5["20"], EnumSimple.ENUM_VALUE_2)
        assertEquals(struct2.f6.size, 2)
        assertEquals(struct2.f6["10"], EnumSimple.ENUM_VALUE_1)
        assertEquals(struct2.f6["20"], null)
        assertEquals(struct2.f7.size, 2)
        assertEquals(struct2.f7["10"], FlagsSimple.fromSet(EnumSet.of(FlagsSimple.FLAG_VALUE_1.value, FlagsSimple.FLAG_VALUE_2.value)))
        assertEquals(struct2.f7["20"], FlagsSimple.fromSet(EnumSet.of(FlagsSimple.FLAG_VALUE_1.value, FlagsSimple.FLAG_VALUE_2.value, FlagsSimple.FLAG_VALUE_3.value)))
        assertEquals(struct2.f8.size, 2)
        assertEquals(struct2.f8["10"], FlagsSimple.fromSet(EnumSet.of(FlagsSimple.FLAG_VALUE_1.value, FlagsSimple.FLAG_VALUE_2.value)))
        assertEquals(struct2.f8["20"], null)
        assertEquals(struct2.f9.size, 2)
        assertEquals(struct2.f9["10"]!!.id, 48)
        assertEquals(struct2.f9["20"]!!.id, 65)
        assertEquals(struct2.f10.size, 2)
        assertEquals(struct2.f10["10"]!!.id, 48)
        assertEquals(struct2.f10["20"], null)
    }
}
